﻿namespace vkUpploaderApp
{
    using System;
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.IO;
    using System.Windows.Forms;

    using vkUpploaderLib;
    using vkUpploaderLib.Exceptions;

    public sealed partial class frmTray : Form
    {
        private bool _closingRequestedFromContextMenu;


        public frmTray()
        {
            InitializeComponent();

            ApplyLocalization();

            if (Properties.Settings.Default.DefaultAlbum == null) {
                ShowSelectAlbumPrompt();
            }

            ScreenResolver r = new ScreenResolver();
            var names = r.GetScreens();
            if (Screen.AllScreens.Length > 1) {
                for (int i = 0; i < Screen.AllScreens.Length; i++) {
                    var item =
                        fromScreenToolStripMenuItem.DropDownItems.Add(
                            string.Format(
                                "{0}{1} : {2}x{3}",
                                Screen.AllScreens[i].Primary ? "*" : string.Empty,
                                names[i],
                                Screen.AllScreens[i].Bounds.Width,
                                Screen.AllScreens[i].Bounds.Height));
                    item.Tag = i;
                    item.Click += OnCaptureSpecificScreen;
                }

                fromScreenToolStripMenuItem.Click -= OnCaptureSpecificScreen;
                fromScreenToolStripMenuItem.Click += CaptureAllScreens;
            }
        }

        private void ApplyLocalization()
        {
            exitToolStripMenuItem.Text = StringResources.Exit;
            fromClipboardToolStripMenuItem.Text = StringResources.FromClipborad;
            fromFileToolStripMenuItem.Text = StringResources.FromFile;
            settingsToolStripMenuItem.Text = StringResources.Settings;

            fromScreenToolStripMenuItem.Text = StringResources.FromScreen;
            fromRegionToolStripMenuItem.Text = StringResources.FromRegion;

            this.Text = StringResources.ProductName;

            notifyIcon1.Text = StringResources.ProductName;
        }

        private void ShowSelectAlbumPrompt()
        {
            if (MessageBox.Show(StringResources.SelectAlbumPromt, StringResources.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Question)
                == DialogResult.Yes) {
                OpenSettings();
            }
        }


        private void FromFile()
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            if (openFileDialog.ShowDialog() == DialogResult.OK) {
                StartAsyncUpload(openFileDialog.FileName, false);
            }
        }

        private void OpenSettings()
        {
            frmSettings f = null;

            try {
                f = new frmSettings();
            }
            catch (VkException e) {
                if (e.Code == VkExceptionsEnum.UserAuthorizationFailed) {
                    if (AuthHelper.Auth()) {
                        Properties.Settings.Default.Token = AuthHelper.Token;
                        Properties.Settings.Default.TokenExpires = AuthHelper.TokenExpires;
                        Properties.Settings.Default.UserID = AuthHelper.UserID;
                        Properties.Settings.Default.Save();
                        try {
                            f = new frmSettings();
                        }
                        catch (Exception ex) {
                            ShowException(ex.Message);   
                        }
                    }
                }
            }

            if (f != null) {
                f.ShowDialog();
            }
        }


        private void fromClipboardToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FromClipboardAsync();
        }

        private void fromFileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FromFile();
        }

        private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenSettings();
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _closingRequestedFromContextMenu = true;
            Close();
        }

        private void frmTray_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (_closingRequestedFromContextMenu && e.CloseReason == CloseReason.UserClosing) {
                if (MessageBox.Show(StringResources.ExitPromt, StringResources.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Question)
                    == DialogResult.Yes) {
                    e.Cancel = false;
                    return;
                }

                e.Cancel = true;
                _closingRequestedFromContextMenu = false;
            }
            if (e.CloseReason == CloseReason.UserClosing) {
                e.Cancel = true;
                Hide();
            }
        }

        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            FromClipboardAsync();
        }

        private void FromClipboardAsync()
        {
            if (Clipboard.ContainsImage()) {
                var image = Clipboard.GetImage();
                string extension = "jpg";
                if (image.RawFormat == ImageFormat.Png) {
                    extension = "png";
                }

                var fileName = string.Format("{0}{1}.{2}", Path.GetTempPath(), Guid.NewGuid().ToString(), extension);
                image.Save(fileName, image.RawFormat);
                StartAsyncUpload(fileName, true);
            }
            else {
                ShowMessage(StringResources.ClipboardEmpty, MessageBoxIcon.Information);
            }
        }

        private void StartAsyncUpload(string fileName, bool deleteFile = false)
        {
            if (Properties.Settings.Default.DefaultAlbum == null) {
                ShowSelectAlbumPrompt();
            }

            WaitForm waitForm = new WaitForm();
            waitForm.Show();
            waitForm.Refresh();
            Application.DoEvents();
            WebUploader webUploader = new WebUploader(this, notifyIcon1);
            webUploader.Completed += waitForm.Close;
            webUploader.Exception += (sender, args) => ShowException(args.Message);
            webUploader.Start(fileName, deleteFile);
        }

        private void ShowException(string message)
        {
            ShowMessage(message, MessageBoxIcon.Stop);
        }

        private DialogResult ShowMessage(string message, MessageBoxIcon type)
        {
            return MessageBox.Show(message, StringResources.ProductName, MessageBoxButtons.OK, type);
        }

        private void frmTray_Shown(object sender, EventArgs e)
        {
            Hide();
        }

        private void OnCaptureSpecificScreen(object sender, EventArgs e)
        {
            int displayIndex = 0;
            var item = sender as ToolStripItem;
            if (item != null) {
                if (item.Tag != null) {
                    try {
                        displayIndex = (int)item.Tag;
                    }
                    catch {}
                }
            }

            CaptureSpecificScreen(displayIndex);
        }

        private void CaptureAllScreens(object sender, EventArgs args)
        {
            //Allow 250 milliseconds for the screen to repaint itself (we don't want to include this form in the capture)
            System.Threading.Thread.Sleep(250);

            Size size = new Size();
            int maxHeight = 0;
            foreach (var screen in Screen.AllScreens) {
                size.Width += screen.Bounds.Size.Width;
                if (maxHeight < screen.Bounds.Size.Height) {
                    maxHeight = screen.Bounds.Size.Height;
                }
            }

            // compute MAX for all screens
            size.Height = maxHeight;

            // Remark VK will cut image after some limit (i.e. width - 3000)
            string fileName;
            using (Bitmap bitmap = new Bitmap(size.Width, size.Height, PixelFormat.Format32bppArgb)) {
                using (Graphics g = Graphics.FromImage(bitmap)) {
                    g.CopyFromScreen(0, 0, 0, 0, size, CopyPixelOperation.SourceCopy);
                }

                fileName = string.Format("{0}{1}.png", Path.GetTempPath(), Guid.NewGuid().ToString());
                bitmap.Save(fileName, ImageFormat.Png);
            }

            StartAsyncUpload(fileName, true);
        }

        private void CaptureSpecificScreen(int displayIndex)
        {
            //Allow 250 milliseconds for the screen to repaint itself (we don't want to include this form in the capture)
            System.Threading.Thread.Sleep(250);

            var displayBounds = Screen.AllScreens[displayIndex].Bounds;

            string fileName;
            using (Bitmap bitmap = new Bitmap(displayBounds.Size.Width, displayBounds.Size.Height, PixelFormat.Format32bppArgb)) {
                using (Graphics g = Graphics.FromImage(bitmap)) {
                    g.CopyFromScreen(displayBounds.X, displayBounds.Y, 0, 0, displayBounds.Size, CopyPixelOperation.SourceCopy);
                }

                fileName = string.Format("{0}{1}.png", Path.GetTempPath(), Guid.NewGuid().ToString());
                bitmap.Save(fileName, ImageFormat.Png);
            }

            StartAsyncUpload(fileName, true);
        }


        private void fromRegionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            int maxHeight = 0;
            int maxWidth = 0;
            frmScreenRegion f = new frmScreenRegion();
            foreach (Screen screen in Screen.AllScreens) {
                if (maxHeight < screen.Bounds.Size.Height) {
                    maxHeight = screen.Bounds.Size.Height;
                }
                maxWidth += screen.Bounds.Size.Width;
            }


            int left = 0;
            int top = 0;
            if (Screen.AllScreens.Length > 1) {
                left = Screen.AllScreens[0].Bounds.Left;
                top = Screen.AllScreens[0].Bounds.Top;
                foreach (var screen in Screen.AllScreens) {
                    if (left > screen.Bounds.Left) {
                        left = screen.Bounds.Left;
                    }
                    if (top > screen.Bounds.Top) {
                        top = screen.Bounds.Top;
                    }
                }
            }

            f.StartPosition = FormStartPosition.Manual;
            f.Left = left;
            f.Top = top;
            f.Size = new Size(maxWidth, maxHeight);

            f.Show();
        }

        public void CaptureImage(Point sourcePoint, Rectangle selectionRectangle)
        {
            System.Threading.Thread.Sleep(250);

            string fileName;
            using (Bitmap bitmap = new Bitmap(selectionRectangle.Size.Width, selectionRectangle.Size.Height, PixelFormat.Format32bppArgb)) {
                using (Graphics g = Graphics.FromImage(bitmap)) {
                    g.CopyFromScreen(sourcePoint.X, sourcePoint.Y, 0, 0, selectionRectangle.Size, CopyPixelOperation.SourceCopy);
                }

                fileName = string.Format("{0}{1}.png", Path.GetTempPath(), Guid.NewGuid().ToString());
                bitmap.Save(fileName, ImageFormat.Png);
            }

            StartAsyncUpload(fileName, true);
        }

        private void cmsTray_Opening(object sender, System.ComponentModel.CancelEventArgs e)
        {
            fromClipboardToolStripMenuItem.Enabled = Clipboard.ContainsImage();
        }
    }
}
